package com.dabai.qrtools.ui;

import static android.os.Environment.DIRECTORY_PICTURES;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.webkit.CookieManager;
import android.webkit.JsResult;
import android.webkit.URLUtil;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ImageView;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bumptech.glide.Glide;
import com.dabai.qrtools.R;
import com.dabai.qrtools.utils.AssetsUtils;
import com.dabai.qrtools.utils.DabaiUtils;
import com.dabai.qrtools.utils.DateUtils;
import com.dabai.qrtools.utils.DownloadUtils;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.permissionx.guolindev.PermissionX;


import java.io.File;


/**
 * 浏览器活动
 *
 * @author 故事与猫
 */
public class BrowserActivity extends AppCompatActivity {

    Context context;
    WebView webView;

    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_browser);

        context = getApplicationContext();

        webView = findViewById(R.id.webView);


        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_outline_clear_24);


        try {
            webInit();
        } catch (Exception e) {
            DabaiUtils.showToast(context,"浏览器初始化异常:"+e.getMessage());
        }

    }


    /**
     * web 初始化
     *
     * @throws Exception
     */
    @SuppressLint("ResourceType")
    private void webInit() throws Exception {

        Uri uri = getIntent().getData();

        if (uri == null) {
            //直接打开
            DabaiUtils.showToast(context, "无效地址!");
            finish();
        } else {
            //其他应用打开
            String link = uri.toString();
            webView.loadUrl(link);
        }


      initWebSetting();


        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            CookieManager.getInstance().setAcceptThirdPartyCookies(webView, true);
        }


        webView.setDownloadListener((url, userAgent, contentDisposition, mimeType, contentLength) -> {
            String fileName = URLUtil.guessFileName(url, contentDisposition, mimeType);

            PermissionX.init(this)
                    .permissions(Manifest.permission.WRITE_EXTERNAL_STORAGE)
                    .request((allGranted, grantedList, deniedList) -> {
                        if (!allGranted) {
                            DabaiUtils.showToast(context, "需要储存权限!");
                        } else {

                            new MaterialAlertDialogBuilder(this)
                                    .setTitle("下载内容")
                                    .setMessage(fileName)
                                    .setPositiveButton("允许下载", (dialog, which) -> {
                                        try {
                                            DabaiUtils.downloadBySystem(context, fileName, url, contentDisposition, mimeType);
                                        } catch (Exception e) {
                                            DabaiUtils.showToast(context, "调用系统下载管理器失败!");
                                        }
                                    })
                                    .setNeutralButton("取消", null)
                                    .show();

                        }
                    });

        });

        /*
          WebViewClient
         */
        webView.setWebViewClient(new WebViewClient() {

            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                super.onPageStarted(view, url, favicon);

                //加载作用域...
                JSONArray jsonArray = JSONArray.parseArray(AssetsUtils.loadAssetsText(context, "jsscope/JsScope.json"));
                for (Object object : jsonArray.toArray()) {
                    JSONObject jsonObject = (JSONObject) object;
                    String jUrl = (String) jsonObject.get("url");
                    JSONArray jsScopes = (JSONArray) jsonObject.get("js_list");

                    //加载全局脚本
                    if ("*".equals(jUrl)) {
                        for (Object object2 : jsScopes.toArray()) {
                            JSONObject jlObject = (JSONObject) object2;
                            AssetsUtils.loadJS(view, jlObject.getString("url"));
                         }
                        //加载 作用于url的脚本
                    } else if (url.contains(jUrl)) {
                        for (Object object2 : jsScopes.toArray()) {
                            JSONObject jlObject = (JSONObject) object2;
                            AssetsUtils.loadJS(view, jlObject.getString("url"));
                            }
                    }
                }
            }

            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                super.shouldOverrideUrlLoading(view, url);


                if (url.startsWith("http:") || url.startsWith("https:") ||
                        url.startsWith("file:") || url.startsWith("content:")) {
                    view.loadUrl(url);
                } else {

                    //拦截百度Scheme
                    String scheme = Uri.parse(url).getScheme();
                    if ("baiduboxapp".equals(scheme) || "baiduboxlite".equals(scheme)) {
                        return true;
                    }

                    new MaterialAlertDialogBuilder(BrowserActivity.this)
                            .setTitle("提示")
                            .setMessage("是否允许使用第三方应用打开[" + scheme + "]协议?")
                            .setPositiveButton("允许", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    try {
                                        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                                        startActivity(intent);
                                    } catch (Exception e) {
                                        DabaiUtils.showToast(context, "第三方应用打开失败!");
                                    }
                                }
                            })
                            .setNeutralButton("取消", null)
                            .show();

                    return true;
                }

                return false;//返回false 意思是不拦截，让webview自己处理
            }

        });

        /*
          WebChromeClient
         */
        webView.setWebChromeClient(new WebChromeClient() {

            // For Android  >= 5.0
            @Override
            public boolean onShowFileChooser(WebView webView,
                                             ValueCallback<Uri[]> filePathCallback,
                                             FileChooserParams fileChooserParams) {
                BrowserActivity.this.uploadFiles = filePathCallback;
                openFileChooseProcess();
                return true;
            }


            @Override
            public void onProgressChanged(WebView view, int newProgress) {

                if (newProgress == 100) {
                    String title = view.getTitle();
                    if (!TextUtils.isEmpty(title)) {
                        getSupportActionBar().setTitle(title);
                    }
                } else {
                    getSupportActionBar().setTitle(newProgress + "%");
                }
            }

            @Override
            public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
                AlertDialog.Builder b = new AlertDialog.Builder(BrowserActivity.this);
                b.setTitle("Alert");
                b.setMessage(message);
                b.setPositiveButton(android.R.string.ok, (dialog, which) -> result.confirm());
                b.setCancelable(false);
                b.create().show();
                return true;
            }

            @Override
            public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
                return super.onJsConfirm(view, url, message, result);
            }
        });

        /*
        注册长按事件
         */
        onWebViewLongClickReg();


    }

    private void initWebSetting() {
        /**
         * 声明WebSettings子类
         */
        WebSettings webSettings = webView.getSettings();
        webSettings.setAllowFileAccess(true);
        webSettings.setAllowContentAccess(true);
        webSettings.setJavaScriptEnabled(true);
        webSettings.setBuiltInZoomControls(true);
        webSettings.setDomStorageEnabled(true);
        webSettings.setAllowFileAccess(true);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            webView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
        }
        webSettings.setUseWideViewPort(true);
        //将图片调整到适合webview的大小
        webSettings.setLoadWithOverviewMode(true);
        // 缩放至屏幕的大小
        webSettings.setSupportZoom(true);
        //支持缩放，默认为true。是下面那个的前提。
        webSettings.setBuiltInZoomControls(true);
        //设置内置的缩放控件。若为false，则该WebView不可缩放
        webSettings.setDisplayZoomControls(false);
        //隐藏原生的缩放控件
        webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
        //关闭webview中缓存
        webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
        //支持通过JS打开新窗口
        webSettings.setLoadsImagesAutomatically(true);
        //支持自动加载图片
        webSettings.setDefaultTextEncodingName("utf-8");
        //设置编码格式
        webSettings.setJavaScriptCanOpenWindowsAutomatically(true);


        postInit();


    }


    private void onWebViewLongClickReg() {

        webView.setOnLongClickListener(view -> {
            WebView.HitTestResult result = webView.getHitTestResult();
            if (null == result) {
                return false;
            }
            int type = result.getType();
            switch (type) {
                case WebView.HitTestResult.EDIT_TEXT_TYPE: // 选中的文字类型
                    break;
                case WebView.HitTestResult.PHONE_TYPE: // 处理拨号
                    break;
                case WebView.HitTestResult.EMAIL_TYPE: // 处理Email
                    break;
                case WebView.HitTestResult.GEO_TYPE: // 　地图类型
                    break;
                case WebView.HitTestResult.SRC_ANCHOR_TYPE: // 超链接
                    break;
                case WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE: // 带有链接的图片类型
                case WebView.HitTestResult.IMAGE_TYPE: // 处理长按图片的菜单项
                    String url = result.getExtra();

                    PermissionX.init(this)
                            .permissions(Manifest.permission.WRITE_EXTERNAL_STORAGE)
                            .request((allGranted, grantedList, deniedList) -> {
                                if (!allGranted) {
                                    DabaiUtils.showToast(context, "需要储存权限!");
                                } else {

                                    View diaView = LayoutInflater.from(context).inflate(R.layout.dialog_save_image, null);
                                    ImageView imageView = diaView.findViewById(R.id.imageView);

                                    Glide.with(context).load(url).into(imageView);

                                    new MaterialAlertDialogBuilder(BrowserActivity.this)
                                            .setTitle("保存图片")
                                            .setView(diaView)
                                            .setPositiveButton("保存图片", (dialog, which) -> DownloadUtils.downloadFile(url, Environment.getExternalStoragePublicDirectory(DIRECTORY_PICTURES) + "/BrowserSave/" + DateUtils.getNowTime(3) + ".jpg", new DownloadUtils.DownloadListener() {
                                                @Override
                                                public void onResult(String state, String filePath, File tagFile) {
                                                    if (tagFile.exists()) {
                                                        // 最后通知图库更新
                                                        sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
                                                                Uri.fromFile(tagFile)));

                                                        runOnUiThread(() -> DabaiUtils.showToast(context, "保存成功!"));
                                                    } else {
                                                        runOnUiThread(() -> DabaiUtils.showToast(context, "保存失败!"));
                                                    }
                                                }

                                                @Override
                                                public void onProgress(String progress, long downed, long length) {
                                                }
                                            }))
                                            .setNeutralButton("取消", null)
                                            .show();

                                }
                            });

                default:
                    break;
            }
            return true;
        });

    }

    private ValueCallback<Uri> uploadFile;
    private ValueCallback<Uri[]> uploadFiles;

    //文件选择
    private void openFileChooseProcess() {
        Intent i = new Intent(Intent.ACTION_GET_CONTENT);
        i.addCategory(Intent.CATEGORY_OPENABLE);
        i.setType("*/*");
        startActivityForResult(Intent.createChooser(i, "上传文件"), 0);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        //上传文件
        if (requestCode == 0) {
            if (resultCode == RESULT_OK) {
                if (null != uploadFile) {
                    Uri result = data == null ? null
                            : data.getData();
                    uploadFile.onReceiveValue(result);
                    uploadFile = null;
                }
                if (null != uploadFiles) {
                    Uri result = data == null ? null
                            : data.getData();
                    uploadFiles.onReceiveValue(new Uri[]{result});
                    uploadFiles = null;
                }
            } else if (resultCode == RESULT_CANCELED) {
                if (null != uploadFile) {
                    uploadFile.onReceiveValue(null);
                    uploadFile = null;
                }
            }
        }
    }


    /**
     * post 信息 判断提交
     */
    public void postInit() {
        /**
         * 如果是 兔小巢 就 把机型信息提交
         */
        if (webView.getUrl().startsWith("https://support.qq.com/")) {
            String openid = DabaiUtils.getDeviceId(this); // 用户的openid
            String nickname = DabaiUtils.getDeviceName(this); // 用户的nickname
            String headimgurl = "https://txc.gtimg.com/static/v2/img/avatar/212.svg";  // 用户的头像url

            /* 获得 webview url，请注意url单词是product而不是products，products是旧版本的参数，用错地址将不能成功提交 */
            String url = webView.getUrl(); // 把1221数字换成你的产品ID，否则会不成功
            /* 准备post参数 */
            String postData = "nickname=" + nickname + "&avatar=" + headimgurl + "&openid=" + openid;
            webView.postUrl(url, postData.getBytes());
        }
    }


    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int itemId = item.getItemId();
        if (itemId == android.R.id.home) {
            finish();
            return true;
        } else if (itemId == R.id.refresh) {
            webView.clearCache(true);
            webView.clearFormData();
            webView.clearHistory();
            webView.loadUrl(webView.getUrl());
            return true;
        } else if (itemId == R.id.copy_address) {

            new MaterialAlertDialogBuilder(BrowserActivity.this)
                    .setTitle("网站信息")
                    .setMessage("标题:"+webView.getTitle()
                    +"\n地址:"+webView.getUrl()
                    +"\n页面高度:"+webView.getContentHeight()+"px")
                    .setNeutralButton("取消",null)
                    .setNegativeButton("复制地址", (dialog, which) -> DabaiUtils.copyText(context, "" + webView.getUrl()))
                    .setPositiveButton("分享", (dialog, which) ->{
                        Intent sendIntent = new Intent();
                        sendIntent.setAction(Intent.ACTION_SEND);
                        // 指定发送内容的类型
                        sendIntent.setType("text/plain");
                        sendIntent.putExtra(Intent.EXTRA_TEXT, webView.getTitle() + "\n" + webView.getUrl());
                        startActivity(Intent.createChooser(sendIntent, "分享文本"));
                    })
                    .show();

            return true;
        } else if (itemId == R.id.using_other_open) {
            DabaiUtils.openLink(context, webView.getUrl());
            return true;
        } else if (itemId == R.id.web_page_back) {
            if (webView.canGoBack()) {
                webView.goBack();
            }
            return true;
        } else if (itemId == R.id.web_page_forward) {
            if (webView.canGoForward()) {
                webView.goForward();
            }
            return true;
        }
        return super.onOptionsItemSelected(item);
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.html_viewer_menu, menu);
        return super.onCreateOptionsMenu(menu);
    }


    //退出时的时间
    private long mExitTime;
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            if (webView.canGoBack()) {
                webView.goBack();//返回上个页面
            } else {
                if ((System.currentTimeMillis() - mExitTime) > 2000) {
                    Toast.makeText(context, "再按一次退出浏览器", Toast.LENGTH_SHORT).show();
                    mExitTime = System.currentTimeMillis();
                } else {
                    finish();
                }
            }
            return true;
        }
        return false;
    }

}